/**********************************************************************************
 * billing head file
 * The billing engineer supports CMCC and UNICOM, and can save, deduct and query 
 * the billing information.
 * 
 * 
 * @author jie.chen@vogins.com
 * @version 1.3.0
 **********************************************************************************/
#ifndef __BILLING_H__
#define __BILLING_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "vmsys.h"

/**
 * pre-install application
 */
#define PAYMENT_APP_SOURCE_FROM_PREINSTALL		(1)

/**
 * download application
 */
#define PAYMENT_APP_SOURCE_FROM_DOWNLOAD		(2)

/**
 * state return callback
 */
typedef VMINT CALLBACK_PAYMENT_STATE;

/**
 * @name vm_quick_charge parameter used in callback
 * @{
 */
/**
 * succeed to charge
 */
#define PAYMENT_STATE_SUCCESS				(0)
/**
 * faile to charge 
 */
#define PAYMENT_STATE_FAILED				(-1)

/**
 * cancel charging.
 */
#define PAYMENT_STATE_CANCEL				(-2)
/** @} */

/**
 * @name billing mode
 * @{
 */
/**
 * charge by time
 */
#define PAYMENT_MODE_BY_TIME				(1)
/**
 * charge by date
 */
#define PAYMENT_MODE_BY_DATE				(2)
/**
 * charge for use forever
 */
#define PAYMENT_MODE_BY_FOREVER				(3)
/** @} */

/**
 * @name return code of billing enginer
 */
#define PAYMENT_RET_SUCCESS					(0)
#define PAYMENT_RET_IN_DURABILITY			(1)
#define PAYMENT_RET_NEED_PAYMENT			(2)
#define PAYMENT_ERR_NO_SIM_CARD				(-1)
#define PAYMENT_ERR_LACK_FS_SPACE			(-2)
#define PAYMENT_ERR_WRONG_PARAM				(-3)
#define PAYMENT_ERR_NO_MEM					(-4)
#define PAYMENT_ERR_CURRENT_DATE			(-5)
#define PAYMENT_ERR_NOT_EXISTS_PAYMENT_ID	(-6)
#define PAYMENT_ERR_IO						(-7)
#define PAYMENT_ERR_INTERNAL_ERROR			(-8)
/** @} */

/**
 * @name return code of vm_quick_charge
 * @{
 */
/**
 * For free payment nodes, the payment process is ignored. The nubmer of days and times are saved.
 * For other payment nodes, the payment is performed. And the nubmer of days and times are saved 
 * after the process succeeds.
 */ 
#define CHARGE_RET_ACCEPT_CHARGE			PAYMENT_RET_SUCCESS
/**
 * No sim card
 */
#define ERROR_CHARGE_RET_NO_SIM_CARD		PAYMENT_ERR_NO_SIM_CARD
/**
 * Insufficient space in file system
 */
#define ERROR_CHARGE_RET_LACK_FS_SPACE		PAYMENT_ERR_LACK_FS_SPACE
/**
 * invalid parameter
 */
#define ERROR_CHARGE_RET_WRONG_PARAM		PAYMENT_ERR_WRONG_PARAM
/**
 * insufficient memory or the request queue is full
 */
#define ERROR_CHARGE_RET_LACK_RESOURCE		PAYMENT_ERR_NO_MEM
/**
 * invalid local date and time (before 2009/1/1)
 */
#define ERROR_CHARGE_RET_CURRENT_DATE_ERROR	PAYMENT_ERR_CURRENT_DATE
/**
 * system error
 */
#define ERROR_CHARGE_RET_INT_ERROR			PAYMENT_ERR_INTERNAL_ERROR
/**
 * appeared in simulator only
 */
#define ERROR_CHARGE_RET_VXP_FILE_ERROR		(PAYMENT_ERR_INTERNAL_ERROR -1)
/**
 * App state error.
 */
#define ERROR_CHARGE_RET_APP_STATE			(PAYMENT_ERR_INTERNAL_ERROR - 2)
/** @} */

/**
 * charge
 * The result is returned by calling the callback function. The function doesn't include UI logicals.
 * If the user need to stop billing process, the function vm_release_charge_resource should be called.
 * @code
 * void myCallBack(VMINT local_payment_id, CALLBACK_PAYMENT_STATE state)
 * {
 *    vm_release_charge_resource();
 *    if (state == PAYMENT_STATE_SUCCESS)
 *    {
 *        vm_save_charge_info("killer", 1, PAYMENT_MODE_BY_TIME, 10);
 *	      game_run();
 *    }
 *    else
 *    {
 *	      // logics for failure
 *	  }
 * }
 * 
 * VMINT ret = 0;
 * if ((ret = vm_query_charge_info("killer", 1, NULL, NULL, NULL) == QUERY_CHARGE_RET_NEED_PAYMENT))
 * {
 *     VMINT errorCode = 0;
 *     if (errorCode = vm_quick_charge("killer", 1, 100, myCallBack, NULL) == CHARGE_RET_ACCEPT_CHARGE)
 *     {
 *         // flush the UI
 *     }
 *     else
 *     {
 *         // fail and return error code
 *     }    
 * }
 * else if (ret == QUERY_CHARGE_RET_IN_DURABILITY)
 * {
 *    vm_deduct_charged_value("killer", 1);
 *    game_run();
 * }
 * else
 * {
 *    // display the failure information
 * }
 * @endcode
 * @param[in] good_name						Goods name to buy, at most 12 character supported.
 * @param[in] local_payment_id 		payment ID that is unique in an application. The range is from 1 to 10000.
 * @param[in] price								the price in cents. If the value is 0, the payment node is free. If the 
 *																value is less than 0, the return value is ERROR_CHARGE_RET_WRONG_PARAM.										
 * @param[in] payment_callback		callback function. If the callback is NULL, user ignores the result.
 * @param[in] extra_content				content added in the message. The max number is 10.
 * @return									return code or error code
 * @retval									CHARGE_RET_ACCEPT_CHARGE billing 	enginer appects the reauest
 * @retval									ERROR_CHARGE_RET_NO_SIM_CARD  		No sim card
 * @retval									ERROR_CHARGE_RET_LACK_FS_SPACE 		Insufficient space in file system
 * @retval									ERROR_CHARGE_RET_NO_SIM_CARD  No SIM card or the network operator is not CMCC or UNICOM.
 * @retval									ERROR_CHARGE_RET_LACK_FS_SPACE File system is lack of space.
 * @retval									ERROR_CHARGE_RET_WRONG_PARAM 			Invalid parameter
 * @retval									ERROR_CHARGE_RET_LACK_RESOURCE 		insufficient memory or the request queue is full
 * @retval									ERROR_CHARGE_RET_CURRENT_DATE_ERROR invalid local date and time (before 2009/1/1)
 * @retval									ERROR_CHARGE_RET_INT_ERROR 				internal error
 * @retval									ERROR_CHARGE_RET_VXP_FILE_ERROR 	If the app_name is NULL, the code will be returned.
 *																														The code appeas in the simulator. In client mobile
 *																														phone, app_name is ignored.
 */
VMINT vm_quick_charge(VMWSTR good_name, VMINT local_payment_id, VMINT price, 
	void (*payment_callback)(VMINT local_payment_id, CALLBACK_PAYMENT_STATE state), VMSTR extra_content, VMINT charge_flag);

/**
 * cancel the payment process
 * The function releases the reaource used to perform billing process. If no callback function is registered or 
 * the sunction is not invoked, the resources will not be released. Appliations should call this function before
 * they exit. In the billing process, calling of the function may cause incorrect charge.
 */
void vm_release_charge_resource(void);

/**
 * @name return code of vm_save_charge_info
 * @{
 */
/**
 * succeed to save
 */
#define SAVE_RET_SUCCESS					PAYMENT_RET_SUCCESS
/**
 * no sim card or unknown operator
 */
#define ERROR_SAVE_RET_NO_SIM_CARD			PAYMENT_ERR_NO_SIM_CARD
/**
 * Insufficient space in file system
 */
#define ERROR_SAVE_RET_LACK_FS_SPACE		PAYMENT_ERR_LACK_FS_SPACE
/**
 * invalid parameter
 */
#define ERROR_SAVE_RET_WRONG_PARAM			PAYMENT_ERR_WRONG_PARAM
/**
 * insufficient memory
 */
#define ERROR_SAVE_RET_LACK_RESOURCE		PAYMENT_ERR_NO_MEM
/**
 * invalid local date and time (before 2009/1/1)
 */
#define ERROR_SAVE_RET_CURRENT_DATE_ERROR	PAYMENT_ERR_CURRENT_DATE
/**
 * internal error
 */
#define ERROR_SAVE_RET_INT_ERROR			PAYMENT_ERR_INTERNAL_ERROR
/**
 * file name error appearing in simulator
 */
#define ERROR_SAVE_RET_VXP_FILE_ERROR		(PAYMENT_ERR_INTERNAL_ERROR - 1)
/**
 * can not get IMSI
 */
#define ERROR_SAVE_RET_NOT_GET_IMSI			(PAYMENT_ERR_INTERNAL_ERROR - 2)
/** @} */
/**
 * svae billing information
 * 
 * @param[in] 				app_name 					The parameter is not NULL and is a string ending with '0x00'.
 * @param[in]					local_payment_id 	payment ID that is unique in an application. The range is from 1 to 10000.
 * @param[in]					payment_mode 			payment mode:
 *																			PAYMENT_MODE_BY_TIME
 *																			PAYMENT_MODE_BY_DATE
 *																			PAYMENT_MODE_BY_FOREVER
 * @param[in]					payment_value 		for PAYMENT_MODE_BY_TIME, the parameter indicates the times that user can 
 *																			play after charge
 *																			for PAYMENT_MODE_BY_DATE, the parameter indicates the number of days that user can 
 *																			play after charge
 *																			for PAYMENT_MODE_BY_FOREVER, the parameter ignores.
 *                          						If the parameter is 0, it same as PAYMENT_MODE_BY_FOREVER
 * @return						return result or error code
 * @retval						SAVE_RET_SUCCESS 	succeed to save
 * @retval						ERROR_SAVE_RET_LACK_FS_SPACE Insufficient space in file system
 * @retval						ERROR_SAVE_RET_WRONG_PARAM invalid parameter
 * @retval						ERROR_SAVE_RET_LACK_RESOURCE insufficient memory
 * @retval						ERROR_SAVE_RET_CURRENT_DATE_ERROR invalid local date and time (before 2009/1/1)
 * @retval						ERROR_SAVE_RET_INT_ERROR internal error
 * @retval						ERROR_SAVE_RET_VXP_FILE_ERROR If the app_name is NULL, the code will be returned.
 *																									The code appeas in the simulator. In client mobile
 *																									phone, app_name is ignored.	
 */
VMINT vm_save_charge_info(VMSTR app_name, VMINT local_payment_id, VMINT payment_mode, VMUINT payment_value);

/**
 * @name return value of vm_deduct_charged_value
 * @{
 */
/**
 * succeed.
 */
#define DEDUCT_CHARGED_RET_SUCCESS								PAYMENT_RET_SUCCESS
/**
 * invalid payment ID
 */
#define ERROR_DEDUCT_CHARGED_RECORD_NOT_FOUND					PAYMENT_ERR_NOT_EXISTS_PAYMENT_ID
/**
 * invalid parameter
 */
#define ERROR_DEDUCT_CHARGED_RET_WRONG_PARAM					PAYMENT_ERR_WRONG_PARAM
/**
 * insufficient resource
 */
#define ERROR_DEDUCT_CHARGED_RET_LACK_RESOURCE					PAYMENT_ERR_NO_MEM
/**
 * invalid local date and time
 */
#define ERROR_DEDUCT_CHARGED_RET_CURRENT_DATE_ERROR				PAYMENT_ERR_CURRENT_DATE
/**
 * no sim card or unknown operator
 */
#define ERROR_DEDUCT_CHARGED_RET_NO_SIM_CARD					PAYMENT_ERR_NO_SIM_CARD
/**
 * internal error
 */
#define ERROR_DEDUCT_CHARGED_RET_INT_ERROR						PAYMENT_ERR_INTERNAL_ERROR
/**
 * failed to get IMSI
 */
#define ERROR_DEDUCT_CHARGED_RET_NOT_GET_IMSI					(PAYMENT_ERR_INTERNAL_ERROR - 1)
/**
 * file name error appearing in simulator
 */
#define ERROR_DEDUCT_CHARGED_RET_EXEC_FILE_PREFIX_ERROR			(PAYMENT_ERR_INTERNAL_ERROR - 2)
/** @} */
/**
 * Deduct the appropriate purchased days and times of charge. If one charge point is within 
 * usable duration, calling of this function will deduct one times and its corresponding days. 
 * To the details of return value and parameter, please refer to API document.
 *
 * @param[in]	app_name 						The parameter is not NULL and is a string ending with '0x00'.
 * @param[in]	local_payment_id 		payment ID that is unique in an application. The range is from 1 to 10000.
 * @return		
 * @retval		DEDUCT_CHARGED_RET_SUCCESS 							succeed
 * @retval		ERROR_DEDUCT_CHARGED_RECORD_NOT_FOUND 	invalid ID
 * @retval		ERROR_DEDUCT_CHARGED_RET_WRONG_PARAM 		invalid parameter
 * @retval		ERROR_DEDUCT_CHARGED_RET_LACK_RESOURCE 	insufficient memory
 * @retval		ERROR_DEDUCT_CHARGED_RET_CURRENT_DATE_ERROR invalid local date and time
 * @retval		ERROR_DEDUCT_CHARGED_RET_INT_ERROR 			internal error
 * @retval		ERROR_DEDUCT_CHARGED_RET_EXEC_FILE_PREFIX_ERROR If the app_name is NULL, the code will be returned.
 *																														The code appeas in the simulator. In client mobile
 *																														phone, app_name is ignored.
 */
VMINT vm_deduct_charged_value(VMSTR app_name, VMINT local_payment_id);

/**
 * @name return code of vm_query_charge_info
 * @{
 */
/**
 * in durability
 */
#define QUERY_CHARGE_RET_IN_DURABILITY			PAYMENT_RET_IN_DURABILITY
/**
 * need to charge
 */
#define QUERY_CHARGE_RET_NEED_PAYMENT			PAYMENT_RET_NEED_PAYMENT
/**
 * invalid parameter
 */
#define QUERY_CHARGE_RET_PARAM_ERROR			PAYMENT_ERR_WRONG_PARAM
/**
 * insufficient memory
 */
#define QUERY_CHARGE_RET_LACK_RESOURCE			PAYMENT_ERR_NO_MEM
/**
 * invalid local date and time
 */
#define QUERY_CHARGE_RET_CURRENT_DATE_ERROR		PAYMENT_ERR_CURRENT_DATE
/**
 * no sim card or unknown operator
 */
#define QUERY_CHARGE_RET_NO_SIM_CARD			PAYMENT_ERR_NO_SIM_CARD
/**
 * internal error
 */
#define QUERY_CHARGE_RET_INT_ERROR				PAYMENT_ERR_INTERNAL_ERROR
/**
 * can not get IMSI
 */
#define QUERY_CHARGE_RET_NOT_GET_IMSI			(PAYMENT_ERR_INTERNAL_ERROR - 1)
/**
 * file name error appearing in simulator
 */
#define QUERY_CHARGE_RET_EXEC_FILE_PREFIX_ERROR (PAYMENT_ERR_INTERNAL_ERROR - 2)
/** @} */

/**
 * query the billing information
 * 
 * @param[in] 	app_name Application name, ect. "killer", this parameter is not NULL and is a string ending with '0x00'. This parameter is only valid in the simulator.
 * @param[in]		local_payment_id payment ID that is unique in an application. The range is from 1 to 10000.
 * @param[out]	payment_mode pointer to buffer that receives payment mode. If QUERY_CHARGE_RET_IN_DURABILITY is returned, 
 * 				the charge method will be written into the address of this parameter. PAYMENT_MODE_BY_TIME means charge by times,
 * 				PAYMENT_MODE_BY_DATE means charge by day; If this function returns QUERY_CHARGE_RET_NEED_PAYMENT 
 * 				this parameter will not be written.
 * @param[out]	payment_surplus_value pointer to buffer that receives surplus value. 
 * 				If this function returns QUERY_CHARGE_RET_IN_DURABILITY, then the remained times or days will be written into 
 * 				the address pointed by this parameter. If in buy out mode, then 0 will be written into this parameter.
 * 				If this function returns QUERY_CHARGE_RET_NEED_PAYMENT, this parameter will not be written.
 * @param[out]	is_saved If the user want to know if the user check charge point is saved when receiving the QUERY_CHARGE_RET_NEED_PAYMENT message,					TRUE 	- saved
 * 				Then this pointer should be provided. Then this function write TRUE or FALSE into the memory address when returning 
 * 				QUERY_CHARGE_RET_NEED_PAYMENT. FALSE means unsaved, TRUE means saved.
 * 				Only when QUERY_CHARGE_RET_NEED_PAYMENT is returned by this function this parameter is written.
 *				
 * @return		Query succeed or not and is in durability.
 * @retval		QUERY_CHARGE_RET_IN_DURABILITY in durability
 * @retval		QUERY_CHARGE_RET_NEED_PAYMENT need to charge
 * @retval		QUERY_CHARGE_RET_PARAM_ERROR invalid parameter
 * @retval		QUERY_CHARGE_RET_LACK_RESOURCE insufficient resource
 * @retval		QUERY_CHARGE_RET_CURRENT_DATE_ERROR invalid local date and time
 * @retval		QUERY_CHARGE_RET_INT_ERROR internal error
 * @retval		QUERY_CHARGE_RET_EXEC_FILE_PREFIX_ERROR If the app_name is NULL, the code will be returned.
 *																									The code appeas in the simulator. In client mobile
 *																									phone, app_name is ignored.
 */
VMINT vm_query_charge_info(VMSTR app_name, VMINT local_payment_id, 
	VMINT* payment_mode, VMINT* payment_surplus_value, VMINT* is_saved);

/**
 * @name Return value of vm_get_charge_notification.
 */
/**
* Enquiry succeed.
*/
#define NOTIFICATION_RET_SUCCESS											(0)
/**
* Wrong parameters.
*/
#define ERROR_NOTIFICATION_RET_WRONG_PARAM									(-1)
/**
* Not enough memory.
*/
#define ERROR_NOTIFICATION_RET_ERROR_MEM									(-2)
/**
* Wrong VXP file.
*/
#define ERROR_NOTIFICATION_RET_VXP_FILE_ERROR								(-3)
/**
* Price dismatched.
*/
#define ERROR_NOTIFICATION_RET_DISMATCH_PRICE								(-4)
/**
 * No notification.
 */
#define ERROR_NOTIFICATION_NO_NOTIFICATION									(-5)

/**
* Get the notification text and the actural price.
* 
* @code
* VMINT ret = 0, transaction_price = 0;
* if ((ret = vm_query_charge_info("ball", 1, NULL, NULL, NULL) == QUERY_CHARGE_RET_NEED_PAYMENT))
* {
*     VMINT errorCode = 0;
*     VMWSTR notification = NULL;
*	 
*	 if (vm_get_charge_notification(200, 1, &transaction_price, &notification) == 0)
*	 {
*	     draw_notification(notification); // Display the notification interface, If user confirmed, invoke vm_quick_charge to start the payment.
*       vm_free(notification);
*     }
* }
* @endcode
* @param[in]								fix_price Price of the charge point defined by the game, unit in cent.
* @param[in]								local_payment_id Internal charge point ID of the application.
* @param[out]								transaction_price Price supported by the charge engine, unit in cent. This price is the input price for invoking the vm_quick_charge function.
* @param[out]								notification Notification text, must be released after being used by vm_free.
* @return									Flag of enquiry result.
* @retval									NOTIFICATION_RET_SUCCESS: Succeed.
* @retval									ERROR_NOTIFICATION_RET_WRONG_PARAM: Wrong parameter.
* @retval									ERROR_NOTIFICATION_RET_ERROR_MEM: Not enough memory.
* @retval									ERROR_NOTIFICATION_RET_VXP_FILE_ERROR: Wrong VXP file.
* @retval									ERROR_NOTIFICATION_RET_DISMATCH_PRICE: Price dismatched.
* @retval									ERROR_NOTIFICATION_NO_NOTIFICATION: No notification in application, the charge engine is responsible for the notification.
*/
VMINT vm_get_charge_notification(VMUINT fix_price, VMINT local_payment_id, VMUINT* transaction_price, VMWSTR* notification);

#ifdef __cplusplus
}
#endif

#endif



